clc;
clear all;
close all;

%% Initial
fprintf('SIMULATOR\n');
N = [4, 8];
lower = 0.0;
upper = 0.9999999999999999;
q = 0.8;

%% Finding the MAE
arr_mae_zr = cell(1, length(N));

for i = 1:length(N)
    fprintf('---------------------MAXIMUM ERROR---------------------------\n');
    fprintf('N = %d\n', N(i));
    
    n = N(i);
    r = n;
    K = 0:(floor(n/4.0) + 2);
    
    step = 2^(-n);
    num = (round((upper-lower)/step) + 1);
    
    max_zr_k = zeros(length(K));
    
    for j = 1:length(K)
        fprintf('\t k = %d\n', K(j));
        k = K(j);                        
        max_zr = 0.0;
        
        index = 0;
        for a = lower:step:upper
            tStart = tic;
            index = index + 1;
            for b = a:step:upper
                
                ans_true = a * b;
                
                ans_zr = trunc_mult(a, b, 0.0, n, n, r, k);
                err_zr = abs(ans_zr - ans_true);
                if (err_zr > max_zr)
                    max_zr = err_zr;
                end                                                
                                                                
            end
            tLoop = toc(tStart);   
            percent = double(index/num) * 100;
            tLeft = tLoop * (num - index);
            fprintf('\t\tN = %d - k = %d - Index = %d - Num = %d - Percent: %f - Time: %s - Left: %f hrs\n',n,k,index, num, percent, datestr(datenum(0,0,0,0,0,tLoop),'HH:MM:SS'),tLeft/3600.0 );
        end

        max_zr_k(j) = max_zr;        
    end
    arr_mae_zr{i} = max_zr_k;    
end
fprintf('\n');

%% Partition
arr_ptt_zr = cell(1, length(N));

for i = 1:length(N)
    fprintf('--------------------PARTITION-----------------------------\n');
    fprintf('N = %d\n', N(i));
    
    n = N(i);
    r = n;
    K = 0:(floor(n/4.0) + 2);
    
    step = 2^(-n);
    num = (round((upper-lower)/step) + 1)^2;
    
    ptt_zr_k = cell(length(K));
    max_zr_k = arr_mae_zr{i};   
    
    for j = 1:length(K)
        fprintf('\t k = %d\n', K(j));
        k = K(j);                        
        ptt_zr = zeros(num);
        
        C1 = max_zr_k(j)/3;
        C2 = C1 * 2;
        
        index = 0;
        for a = lower:step:upper
            tStart = tic;
            index = index + 1;
            for b = lower:step:upper
                ans_true = a * b;
                ans_C1 = trunc_mult(a, b, C1, n, n, r, k);
                ans_C2 = trunc_mult(a, b, C2, n, n, r, k);
                err_C1 = abs(ans_C1 - ans_true);
                err_C2 = abs(ans_C2 - ans_true);
                if (err_C1 > err_C2)
                    ptt_zr(index) = 2;
                else
                    ptt_zr(index) = 1;
                end                                                                                                               
            end
            tLoop = toc(tStart);   
            percent = double(index/num) * 100;
            tLeft = tLoop * (num - index);
            fprintf('\t\tN = %d - k = %d - Index = %d - Num = %d - Percent: %f - Time: %s - Left: %f hrs\n',n,k,index, num, percent, datestr(datenum(0,0,0,0,0,tLoop),'HH:MM:SS'),tLeft/3600.0 );
        end

        ptt_zr_k{j} = ptt_zr;        
    end
    arr_ptt_zr{i} = ptt_zr_k;    
end
fprintf('\n');

%% Printing result
fprintf('Printing result...\n');
for i = 1:length(N)
    n = N(i);
    K = 0:(floor(n/4.0) + 2);
    ptt_zr_k = arr_ptt_zr{i} ;  
    for j = 1:length(K)
        ptt_zr = ptt_zr_k{j};  
        figure;
        plot(ptt_zr(:));
    end
end
